//@author A0096440E
#pragma once
#ifndef TASKITSCHEDULER_H_
#define TASKITSCHEDULER_H_

#include "TaskItGlobal.h"
#include "TaskItStorage.h"
#include "StringParser.h"
#include "Logger.h"
#include "QuickAddStringParser.h"

//TaskItScheduler class for TaskIt. This class forms the Logic component of the
//whole program. It will perform and execute all commands set by the users and do
//multiple checks and guards against invalid parameters set by the users. Once a
//certain command and parameters is successfully cleared by all the checks., it will
//proceed to call TaskItStorage object to store the task, delete the task, etc.
class TaskItScheduler {

private:
	TaskItStorage _myStorage;
	StringParser _infoString;
	QuickAddStringParser _specialStringParser;
	vector <string> _displayVector;
	vector <int> _displayIndexes;
	string _displayMode;
	string _keyword;
	CommandType _previousCommand;
	CommandType _currentCommand;

public:
	TaskItScheduler();

	//This function is to initialize the program by retrieving all the
	//tasks stored by a file.
	//Pre-Req: Owner name or name of File.
	//Post-Req: All tasks retrieved and program good to go.
	void setOwnerName(string owner);
	//This function is to display out the first welcome message of the program.
	//Pre-Req: A reference boolean variable 'smallUI'.
	//Post-Req: Return the welcome message to UI component.
	string initialWelcome(bool &smallUI);
	//This function will sieve out all tasks that are not done in the past and
	//all tasks that are needed today.
	//Pre-Req: A reference boolean variable 'smallUI'.
	//Post-Req: Return a vector of strings containing all the details of the
	//			tasks needed to the UI component.
	vector <string> viewToday(bool &smallUI);
	//Given a user input, this function will determine the command and execute the command.
	//Pre-Req: Takes in a string containing relevant information for processing and
	//		   a reference boolean variable 'smallUI'.
	//Post-Req: It will first attempt to split the string input into different parameters
	//			for processing. If it fails, it will throw an invalid message. Else, it will
	//			sieve out the command and call it relevant function in TaskItScheduler. If
	//			there are any invalid parameters found in any of the relevant function, it
	//			will catch the invalid message and return it to the UI component. If everything
	//			is successful, it will return a vector of strings containing the information
	//			for UI to display.
	vector <string> executeCommand(string allInfo, bool &smallUI);
	//This is the getter function to a vector of integers, containing all the dates inside the tasks 
	//that the user have added.
	//Pre-Req: None.
	//Post-Req: Dates will be converted to integers and returns as a vector of integers.
	vector <int> getDatesWithTasks();

	//This function will add the task that the user determines.
	//Pre-Req: Takes in six strings containing the information parameters
	//		   of the tasks to be added.
	//Post-Req: The function will do multiple checks to prevent invalid tasks
	//			parameters from passing the program. If there is an invalid tasks
	//			parameter detected, an invalid message will be returned. If all
	//			parameters are valid, the task will be checked to see if there is
	//			a clash with any tasks added before. If there is a clash, a warning
	//			message will be returned. If everything is fine, then the task will
	//			be added to the storage.
	string addTask(string info2, string info3, string info4, string info5, string info6, string info7);
	//This function will add the task that was found to have clash but the user
	//still wants to add.
	//Pre-Req: None.
	//Post-Req: Task will be added to the storage and a successful message will
	//			be returned.
	string addConflictedTask();
	//This function would not add the task that was found to have clash as the
	//user has indicated not to add.
	//Pre-Req: None.
	//Post-Req: Task will be not be added to the storage and a successfully not
	//			added message will be returned.
	string doNotAddConflictedTask();
	//This function will delete the floating task that the user determines.
	//Pre-Req: Takes in a string info2 which contains the index
	//		   of the position of task to delete.
	//Post-Req: If the index is out of bounds, an invalid string is returned.
	//			If the index is valid, the task will be deleted and a successful
	//			message string will be returned.
	string fDeleteTask(string info2);
	//This function will delete the task that the user determines.
	//Pre-Req: Takes in a string info2 which contains the index
	//		   of the position of task to delete.
	//Post-Req: If the index is out of bounds, an invalid string is returned.
	//			If the index is valid, the task will be deleted and a successful
	//			message string will be returned.
	string deleteTask(string info2);
	//This function will edit the task that the user determines.
	//Pre-Req: Takes in a string info2 that is the index position of the task to be
	//		   edited. Takes in six strings containing the information parameters
	//		   of the tasks to be edited.
	//Post-Req: The function will do multiple checks to prevent invalid tasks
	//			parameters from passing the program. If the index is out of bounds,
	//			an invalid string is returned. If there is an invalid tasks
	//			parameter detected, an invalid message will be returned. If all
	//			parameters are valid, the task will be checked to see if there is
	//			a clash with any tasks added before. If there is a clash, a warning
	//			message will be returned and the task will still be edited. If
	//			everything is fine, then the task will be edited in the storage.
	string editTask(string info2, string info3, string info4, string info5, string info6, string info7, string info8);
	//This function will edit the floating task that the user determines.
	//Pre-Req: Takes in a string info2 that is the index position of the task to be
	//		   edited. Takes in six strings containing the information parameters
	//		   of the tasks to be edited.
	//Post-Req: The function will do multiple checks to prevent invalid tasks
	//			parameters from passing the program. If the index is out of bounds,
	//			an invalid string is returned. If there is an invalid tasks
	//			parameter detected, an invalid message will be returned. If all
	//			parameters are valid, the task will be checked to see if there is
	//			a clash with any tasks added before. If there is a clash, a warning
	//			message will be returned and the task will still be edited. If
	//			everything is fine, then the task will be edited in the storage.
	string fEditTask(string info2, string info3, string info4, string info5, string info6, string info7, string info8);
	//This function will allow the UI to retrieve the task that the user want
	//to edit at live time.
	//Pre-Req: Takes the index position of the task to be edited and a boolean
	//		   reference variable isValid.
	//Post-Req: If the index is out of bounds, an invalid string is returned and
	//			isValid variable will be false. If the index is within range,
	//			the task details will be returned to the user and isValid variable
	//			will be true.
	string checkEditIndex(string indexString, bool &isValid);
	//This function will allow the UI to retrieve the floating task that
	//the user want to edit at live time.
	//Pre-Req: Takes the index position of the task to be edited and a boolean
	//		   reference variable isValid.
	//Post-Req: If the index is out of bounds, an invalid string is returned and
	//			isValid variable will be false. If the index is within range,
	//			the task details will be returned to the user and isValid variable
	//			will be true.
	string checkFEditIndex(string indexString, bool &isValid);
	//This function will allow the user to mark any particular task as not done.
	//Pre-Req: Takes in a string info2 which contains the index
	//		   of the position of task to mark undone.
	//Post-Req: If the index is out of bounds, an invalid string is returned.
	//			If index is valid but task is not marked, an invalid string
	//			is returned. If index is valid and task marked done, it will
	//			mark task as not done and return a successful string.
	string unMarkTask(string info2);
	//This function will allow the user to mark any particular task as done.
	//Pre-Req: Takes in a string info2 which contains the index
	//		   of the position of task to mark done.
	//Post-Req: If the index is out of bounds, an invalid string is returned.
	//			If index is valid but task is already marked, an invalid string
	//			is returned. If index is valid and task not yet mark, it will
	//			mark task as done and return a successful string.
	string markTask(string info2);
	//This function will allow the user to block slots for any unconfirmed tasks.
	//Pre-Req: Takes in 6 strings which contains the details of the tasks to be
	//		   blocked.
	//Post-Req: If there is no activity detected, an invalid string is returned.
	//			If there is an activity, function will call addTask to add the
	//			tasks to the storage.
	string block(string info2, string info3, string info4, string info5, string info6, string info7);
	//This function will allow the user to confirms his activity
	//on his blocked slots.
	//Pre-Req: Takes in a string info2 which contains the index
	//		   of the position of task to confirm.
	//Post-Req: If the index is out of bounds, an invalid string is returned.
	//			If the index is within bounds, but does not correspond to
	//			any block slots, an invalid string is returned. If index is valid,
	//			the confirm slot will be confirmed by the program and all other
	//			blocked slots will be removed.
	string confirm(string info2);
	//This function will allow the user to undo the previous action.
	//Pre-Req: None.
	//Post-Req: If there is no previous action, a string showing no
	//			action to undo will be return. Else, the most immediate
	//			previous action will be undone and a string showing
	//			successful undo will be returned.
	string undoTask();
	//This function will show the user the list of available commands.
	//Pre-Req: None.
	//Post-Req: It will return a string containing the list of commands.
	string helpTask();
	//This function will call TaskItStorage to execute a clear of
	//all tasks that has pass and are already marked done.
	//Pre-Req: None.
	//Post-Req: It will prompt the user a warning sign. If user type
	//			'y', all previous done tasks will be deleted and undo
	//			capabilities restarted. If the user type 'n', then
	//			nothing will be done.
	string clearTasks();

	//This function is to check whether there is a clash of timing
	//between two tasks timing.
	//Pre-Req: Takes in four TaskItTime objects to check for clash.
	//Post-Req: If a clash is found, the function will return true,
	//			else the function will return false.
	bool checkClash(TaskItTime newStartTime, TaskItTime newEndTime, TaskItTime currentStartTime, TaskItTime currentEndTime);

	//@author A0096509U
	//This function is to sieve out which criteria of view that the user
	//determine and will call the appropriate function.
	//Pre-Req: Take in a string info2 and a reference boolean variable 'smallUI'.
	//Post-Req: Function will check whether info2 is to viewAll, viewDate or
	//			viewCategory and execute the correct command.
	void viewTask(string info2, bool &smallUI);
	//This function is to view all the tasks that the user has.
	//Pre-Req: Take in a string info2 and a reference boolean variable 'smallUI'.
	//Post-Req: Function will search for all tasks and store it in a vector for 
	//			UI to access. If there is no tasks at all, then a no task message
	//			will be stored for UI component and smallUI will be false.
	//			Tasks that are not done will be displayed before tasks that are done.
	void viewAll(bool &smallUI);
	//This function is to view all the tasks by the category that is determine
	//by the user.
	//Pre-Req: Take in a string info2 and a reference boolean variable 'smallUI'.
	//Post-Req: Function will search for all tasks on the particular category
	//			and store it in a vector for UI to access. If there is no tasks at
	//			all, then a no task message will be stored for UI component and
	//			smallUI will be false.
	//			Tasks that are not done will be displayed before tasks that are done.
	void viewCategory(string info2, bool &smallUI);
	//This function is to view all the tasks by the date that is determine
	//by the user.
	//Pre-Req: Take in a string info2 and a reference boolean variable 'smallUI'.
	//Post-Req: Function will check whether the date determine by user is valid. If
	//			it is invalid, function will recieve a error message. If the date is
	//			valid, the function will search for all tasks on the particular date
	//			and store it in a vector for UI to access. If there is no tasks at
	//			all, then a no task message will be stored for UI component and
	//			smallUI will be false.
	void viewDate(string info2, bool &smallUI);
	//This function is to store the task details as well as the position
	//of the task.
	//Pre-Req: Takes in a Task object and an int index position.
	//Post-Req: Function will store the task object details as well as 
	//			the index position of the task.
	void storeToDisplayVector(Task task, int index);
	//This function will refresh the floating task UI component after each action
	//done by the user so that the user will have the latest view.
	//Pre-Req: None.
	//Post-Req: Returns a string that contains all the floatings tasks in the program.
	//			String will be empty if there are no floating tasks.
	string refreshFloatingTasksWindow();
	//This function will refresh the UI component after each action done by the user
	//so that the user will have the latest view.
	//Pre-Req: A reference boolean variable 'smallUI'.
	//Post-Req: Return a vector of strings containing all the details of the
	//			updated tasks needed to the UI component.
	//			If there is nothing to view, smallUI will return as false.
	vector <string> refreshBigWindow(bool &smallUI);

	//@author A0096440E
	//This function is to search for a keyword in the activity in all Tasks.
	//Pre-Req: Takes in the string info2 which is the keyword and the
	//		   reference boolean variable 'smallUI'.
	//Post-Req: If the keyword is found in any activity, UI component can
	//			retrieve those tasks TaskItScheduler, else if the keyword is
	//			not found, then a error message is stored for UI to retrieve.
	void searchTask(string info2, bool &smallUI);
	
	//This function is to check whether the time object is valid.
	//Pre-Req: Takes in one reference TaskItTime object and one string timeString.
	//Post-Req: If the timeString is invalid, the function will throw an invalid message.
	void checkValidTime(TaskItTime &time, string timeString);
	//This function is to check whether the time objects is in invalid combination
	//with each other.
	//Pre-Req: Takes in two reference TaskItTime objects - timeStart and timeEnd
	//		   and two strings - timeStartString and timeEndString.
	//Post-Req: If the start time is later then the end time then the function will
	//			throw an invalid message.
	void checkValidCombinationTime(TaskItTime &timeStart, TaskItTime &timeEnd, string timeStartString, string timeEndString);
	//This function is to check whether there exist an activity in the task to be added.
	//Pre-Req: Takes in a string activity.
	//Post-Req: If there exists no activity, the function will throw an invalid message.
	void checkValidActivity(string activity);
	//This function is to check whether there exists a Date when time exists.
	//Pre-Req: Takes in three strings - date, timeStartString, timeEndString.
	//Post-Req: If time exists but there is no date indicated, the function will
	//			throw an invalid message.
	void checkValidDateWithTime(string date, string timeStartString, string timeEndString);
	//This function is to check whether the date is valid.
	//Pre-Req: Takes in one reference Date object, a string dateString
	//		   and one integer date.
	//Post-Req: If the date is invalid, the function will throw an invalid message.
	void checkValidDate(Date &newDate, string dateString, int date);

	//This is to append any newline strings to the display string.
	//Pre-Req: Takes is an original string info.
	//Post-Req: Returns a string containing a newline at the rear.
	string showToUser(string info);

	//This function is to determine the command set by the user.
	//Pre-Req: Takes in a string command.
	//Post-Req: Returns the enum version of command for switch case usage.
	CommandType determineCommandType(string command);
};

#endif